import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { AppModule } from '../src/app.module';
import { MongooseModule, getModelToken } from '@nestjs/mongoose';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { User } from '../src/schemas/users/user.schema';
import { MongoMemoryServer } from 'mongodb-memory-server';
import { AuthService } from '../src/auth/auth.service';
import { JwtService } from '@nestjs/jwt';

// Mock短信服务
jest.mock('../src/auth/auth.service', () => ({
  AuthService: jest.fn().mockImplementation(() => ({
    sendSMSCode: jest.fn().mockResolvedValue(undefined),
    loginBySMS: jest.fn().mockImplementation((mobile, code) => ({
      token: 'mock_jwt_token'
    })),
  })),
}));

describe('AppController (e2e)', () => {
  let app: INestApplication;
  let mongoServer: MongoMemoryServer;
  let authService: AuthService;
  let userModel = getModelToken(User.name);
  let adminToken: string;
  let userToken: string;

  beforeAll(async () => {
    // 启动内存MongoDB
    mongoServer = await MongoMemoryServer.create();
    const mongoUri = mongoServer.getUri();

    const moduleFixture: TestingModule = await Test.createTestingModule({
      imports: [
        ConfigModule.forRoot({ envFilePath: '.env.test' }),
        MongooseModule.forRoot(mongoUri),
        AppModule,
      ],
    })
      .overrideProvider(AuthService)
      .useClass(AuthService) // 使用Mock的AuthService
      .compile();

    app = moduleFixture.createNestApplication();
    await app.init();

    // 初始化依赖
    authService = moduleFixture.get<AuthService>(AuthService);
    const configService = moduleFixture.get<ConfigService>(ConfigService);
    const jwtService = new JwtService({ secret: configService.get('JWT_SECRET') });

    // 生成管理员Token
    adminToken = jwtService.sign({ mobile: 'admin', roles: ['ADMIN'] });
    // 生成普通用户Token
    userToken = jwtService.sign({ mobile: '13800000000', roles: ['USER'] });
  });

  afterEach(async () => {
    // 清理所有集合数据
    const mongoose = app.get('DatabaseConnection');
    for (const collection of Object.values(mongoose.connection.collections)) {
      await collection.deleteMany({});
    }
  });

  afterAll(async () => {
    await app.close();
    await mongoServer.stop();
  });

  // --------------------------
  // 用户认证接口测试
  // --------------------------
  describe('AuthController', () => {
    it('POST /auth/sms/send - 成功发送验证码 (Mock)', async () => {
      const mobile = '13800000000';
      await request(app.getHttpServer())
        .post('/auth/sms/send')
        .send({ mobile })
        .expect(200)
        .expect(res => {
          expect(res.body.code).toBe(200);
          expect(res.body.message).toContain('验证码已发送');
        });
      expect(authService.sendSMSCode).toHaveBeenCalledWith(mobile);
    });

    it('POST /auth/sms/login - 使用Mock验证码登录', async () => {
      await request(app.getHttpServer())
        .post('/auth/sms/login')
        .send({ mobile: '13800000000', code: '123456' })
        .expect(200)
        .expect(res => {
          expect(res.body.data.token).toBe('mock_jwt_token');
        });
    });
  });

  // --------------------------
  // 题目管理接口测试（管理员权限）
  // --------------------------
  describe('QuestionsController (Admin)', () => {
    let questionId: string;

    it('POST /questions - 创建单选题（带图片）', async () => {
      const response = await request(app.getHttpServer())
        .post('/questions')
        .set('Authorization', `Bearer ${adminToken}`)
        .field('content', 'NestJS是什么？')
        .field('type', 'single')
        .field('category', '行政职业能力测试')
        .field('correctAnswer', 0)
        .field('options', JSON.stringify(['框架', '库']))
        .attach('images', Buffer.from('test'), 'test.png')
        .expect(201);

      questionId = response.body._id;
      expect(response.body.content).toBe('NestJS是什么？');
      expect(response.body.imageUrls.length).toBe(1);
    });

    it('DELETE /questions/:id - 删除题目', async () => {
      await request(app.getHttpServer())
        .delete(`/questions/${questionId}`)
        .set('Authorization', `Bearer ${adminToken}`)
        .expect(200)
        .expect(res => {
          expect(res.body.deleted).toBe(true);
        });
    });
  });

  // --------------------------
  // 考试管理接口测试
  // --------------------------
  describe('ExamsController', () => {
    let examId: string;

    beforeAll(async () => {
      // 创建考试
      const examRes = await request(app.getHttpServer())
        .post('/exams/create')
        .set('Authorization', `Bearer ${adminToken}`)
        .send({
          title: '全真模拟考试',
          type: '全真模考',
          sections: [{
            name: '行测',
            duration: 120,
            questions: []
          }]
        });
      examId = examRes.body._id;
    });

    it('POST /exams/:id/submit - 提交考试答案', async () => {
      await request(app.getHttpServer())
        .post(`/exams/${examId}/submit`)
        .set('Authorization', `Bearer ${userToken}`)
        .send({
          '0-question1': 1,
          '0-question2': [0, 2]
        })
        .expect(201)
        .expect(res => {
          expect(res.body.totalScore).toBeDefined();
        });
    });
  });
});